import requests
import json
import datetime
# import keyboard
import os
from queue import Queue

messages_queue = Queue()

api_key = os.environ.get("MOONSHOT_API_KEY")
if not api_key:
    api_key = input("请输入 Moonshot API Key：")


def make_request_json(prompt: str, user_input: str, model: str, temperature: float = 0.3, stream: bool = True,
                      n: int = 1, name: str = None, use_webtool: bool = False, history: list = None):
    messages = [
        {"role": "system", "content": f"{prompt}"},
    ]
    if history is not None and len(history) > 0 and history[0] != "":
        messages += history
    messages.append({"role": "user", "content": f"{user_input}"})
    if name and name != "":
        messages.append({"role": "assistant", "name": f"{name}", "content": "", "partial": True})

    data = {
        "model": f"{model}",
        "messages": messages,
        "temperature": temperature,
        "stream": stream,  # 流式响应
        "n": n,  # 最多返回1个结果
    }
    if use_webtool:
        data["tools"] = [{"type": "builtin_function", "function": {"name": "$web_search"}}]
    return data


def get_response(API_KEY, jsons, user_input):
    history_dict_lst = []
    contents = ""
    headers = {
        "Authorization": f"Bearer {API_KEY}",
        "Content-Type": "application/json"
    }
    r = requests.post("https://api.moonshot.cn/v1/chat/completions", json=jsons, headers=headers, stream=True)
    # 检查响应状态码
    if r.status_code != 200:
        if r.status_code == 429:
            print("请求频率太快了，1分钟内不能大于3次哦")
        else:
            raise Exception(f"请求失败，错误代码: {r.status_code}, 错误信息: {r.text}")
    print("对方：")
    data = ""  # 初始化为字符串
    # 流式输出响应内容，使用 iter_lines 方法来逐行读取响应体
    for line in r.iter_lines():
        # 去除每一行收尾的空格，以便更好地处理数据块
        line = line.strip().decode("utf-8")
        # 1. 如果当前行是空行，则表明前一个数据块已接收完毕（即前文提到的，通过两个换行符结束数据块传输），我们可以对该数据块进行反序列化，并打印出对应的 content 内容；
        # 2. 如果当前行为非空行，且以 data: 开头，则表明这是一个数据块传输的开始，我们去除 data: 前缀后，首先判断是否是结束符 [DONE]，如果不是，将数据内容保存到 data 变量；
        # 3. 如果当前行为非空行，但不以 data: 开头，则表明当前行仍然归属上一个正在传输的数据块，我们将当前行的内容追加到 data 变量尾部；
        if len(line) == 0:
            if data:
                try:
                    chunk = json.loads(data)  # 解析数据块
                    for choice in chunk["choices"]:
                        delta = choice["delta"]
                        content = delta.get("content")
                        if content:
                            contents += content
                            print(content, end="")
                            messages_queue.put(content)
                    data = ""  # 重置 data
                except json.JSONDecodeError as e:
                    print(f"JSON 解码错误: {e}")
                    messages_queue.put(f"JSON 解码错误: {e}")
        elif line.startswith("data: "):
            data = line.lstrip("data: ")
            # 当数据块内容为 [DONE] 时，则表明所有数据块已发送完毕，可断开网络连接
            if data == "[DONE]":
                print("\n")
                history_dict_lst.append({"role": "user", "content": f"{user_input}"})
                history_dict_lst.append({"role": "assistant", "content": f"{contents}"})
                break
        else:
            data += "\n" + line  # 继续追加当前行内容
    return history_dict_lst





def chat_main(input_str):
    start_time = datetime.datetime.now()
    with open("预设提示词/爱莉希雅.prompt", "r", encoding="utf-8") as f:
        prompt = f.read()
    model_lst = ["占位", "moonshot-v1-8k", "moonshot-v1-32k", "moonshot-v1-128k", "moonshot-v1-auto"]
    model = model_lst[4]
    t = make_request_json(prompt, input_str, model, name="爱莉希雅")
    reply=get_response(api_key, t, input_str)[1]["content"]
    end_time = datetime.datetime.now()
    print(f"生成对话用时：{(end_time - start_time).seconds} 秒")
    return reply
#
# def make_sure_enter():
#     while True:
#         event = keyboard.read_event()  # 等待键盘事件c
#         if event.event_type == keyboard.KEY_DOWN:  # 只处理按键按下事件
#             if event.name == 'y':  # 按下 'y' 键时返回 True
#                 return True
#             else:  # 按下其他键时返回 False
#                 return False


# chat_main("你好，我是爱莉希雅，你叫什么名字？")
# if __name__ == '__main__':
#
#     with open("example.prompt", "r", encoding="utf-8") as f:
#         prompt = f.read()
#     model_lst = ["占位", "moonshot-v1-8k", "moonshot-v1-32k", "moonshot-v1-128k", "moonshot-v1-auto"]
#     model = model_lst[4]
#     print("是否使用历史对话？(y/other)")
#     use_history = make_sure_enter()
#     if use_history:
#         history_path = input("请输入历史对话文件路径与文件名：")
#         with open(f"{history_path}", "r", encoding="utf-8") as f:
#             history = json.load(f)
#     else:
#         history = []
#     print("是否使用预填充以及加强自我认知（输入姓名）？(y/other)")
#     use_name=make_sure_enter()
#     if use_name:
#         name = input("输入姓名：")
#     else:
#         name = ""
#     while True:
#         try:
#             user_input_text = input("你：")
#             data_json = make_request_json(prompt, user_input_text, model, name=f"{name}", history=history)
#             # print(f"请求数据：{data_json}")
#             temp = get_response(api_key, data_json, user_input_text)
#             history += temp
#             # print(f"对话历史：{history}")
#             log_time = datetime.datetime.now().strftime("%Y-%m-%d_%H_%M")
#             if name!= "":
#                 with open(f"./log/{name}_{log_time}.history.json", "w", encoding="utf-8") as f:
#                     json.dump(history, f, ensure_ascii=False, indent=4)
#             else:
#                 with open(f"./log/无姓名_{log_time}.history.json", "w", encoding="utf-8") as f:
#                     json.dump(history, f, ensure_ascii=False, indent=4)
#         except Exception as e:
#             print(f"发生错误：{e}")
